package com.hk.system.config;


import dubhe.token.api.authentication.AuthenticationAwareToken;
import dubhe.token.api.authentication.DefaultTokenAuthentication;
import dubhe.token.api.authentication.principal.Principal;
import dubhe.token.api.factory.TimeoutTokenFactory;
import dubhe.token.api.factory.TokenFactory;
import dubhe.token.api.model.TimeoutAccessToken;
import dubhe.token.api.model.Token;
import dubhe.token.api.registry.TokenRegistry;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * @author miaoj
 */
@RequiredArgsConstructor
public class DatabaseAuthenticationProvider extends DaoAuthenticationProvider {

    private final TokenFactory tokenFactory;

    private final TokenRegistry tokenRegistry;

    @Override
    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {
        if (user instanceof UserDetailsServiceImpl.LoginUserDetails) {
            UserDetailsServiceImpl.LoginUserDetails loginUserDetails = (UserDetailsServiceImpl.LoginUserDetails) user;
            final dubhe.token.api.authentication.Authentication tokenAuthentication = new dubhe.token.api.authentication.Authentication(
                    Principal.builder()
                            .id(loginUserDetails.getUsername())
                            .userInfo(loginUserDetails.getUserInfo())
                            .build());
            final TimeoutTokenFactory factory = (TimeoutTokenFactory) tokenFactory.get(TimeoutAccessToken.class);
            Token token = factory.create(tokenAuthentication);
            loginUserDetails.getUserInfo().setAccessToken(token.getId());
            loginUserDetails.getUserInfo().setAuthenticated(true);
            try {
                tokenRegistry.addToken(token);
            } catch (Exception e) {
                throw new RuntimeException("生成token出错");
            }
            AuthenticationAwareToken authenticationAwareToken = (AuthenticationAwareToken) token;
            return new DefaultTokenAuthentication(authenticationAwareToken.getAuthentication(), token.getId());
        }
        throw new RuntimeException("用户信息异常");
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication == UsernamePasswordAuthenticationToken.class;
    }
}
